/**
 * All rights Reserved, Designed By OprCalf
 * Copyright:    Copyright(C) 2016-2020
 * Company       OprCalf Ltd.
 */

package com.platform.gateway.common.aspect;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.base.Strings;
import com.platform.gateway.common.annotation.Security;
import com.platform.gateway.common.utils.MsgUtils;

import lombok.extern.slf4j.Slf4j;

/**@projectName:  platform-gateway
 * @package:      com.platform.gateway.common.aspect
 * @className:    SecurityAspect.java
 * @description:  鉴权界面
 * @author:       OprCalf
 * @date:         2019年5月22日
 */
@Component
@Aspect
@Slf4j
public class SecurityAspect {

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private HttpServletRequest request;

    @Pointcut("@annotation(com.platform.gateway.common.annotation.Security)")
    public void serviceSecurity() {
    }

    @Around("serviceSecurity()")
    public Object around(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
        try {
            Object obj = null;
            // 获取拦截的方法名
            final Signature sig = joinPoint.getSignature();
            // 获取拦截的方法名
            final MethodSignature msig = (MethodSignature) sig;
            // 返回被织入增加处理目标对象
            final Object target = joinPoint.getTarget();
            // 为了获取注解信息
            final Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
            // 获取注解信息
            final Security annotation = currentMethod.getAnnotation(Security.class);
            // 当不为空的时候,此时我们需要对此方法进行鉴权
            if (annotation != null) {
                final String token = request.getHeader("access_token");
                if (Strings.isNullOrEmpty(token)) {
                    // 拒绝了请求（服务降级）
                    log.info("拒绝了请求：" + request.getRequestURI());
                    response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
                    response.setContentType("application/json;charset=UTF-8");
                    response.getOutputStream()
                    .write(MsgUtils.buildFailureMsg("当前请求没有token").toString().getBytes("utf-8"));
                } else {
                    final String tokenValue = "nc3yb4x9n24nty23nu034bry9cy359-x23n4-x";
                    if (!tokenValue.equals(token)) {
                        response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
                        response.setContentType("application/json;charset=UTF-8");
                        response.getOutputStream()
                        .write(MsgUtils.buildFailureMsg("当前token不正确").toString().getBytes("utf-8"));
                    } else {
                        obj = joinPoint.proceed();
                    }
                }
            }
            return obj;
        }
        catch (final Throwable throwable) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.setContentType("application/json;charset=UTF-8");
            try {
                response.getOutputStream()
                .write(MsgUtils.buildFailureMsg(throwable.getLocalizedMessage()).toString().getBytes("utf-8"));
            }
            catch (final Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
}
